using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.ServiceModel;
using Microsoft.TeamFoundation.Client;
using System.Diagnostics;

namespace Callista.TFSBuildAlert
{
    public class Program : ApplicationContext
    {
        private System.ComponentModel.IContainer components;
        private System.Windows.Forms.NotifyIcon tfsBuildAlertNotifyIcon;
        private System.Windows.Forms.ContextMenu tfsBuildAlertNotifyIconContextMenu;
        private System.Windows.Forms.MenuItem settingsContextMenuItem;
        private System.Windows.Forms.MenuItem resetContextMenuItem;
        private System.Windows.Forms.MenuItem exitContextMenuItem;
        private System.Windows.Forms.Form settingsForm = null;
        private Icon _okIcon = null;
        private Icon _brokenIcon = null;
        private ServiceHost _notificationHost = null;
        private TeamFoundationServer _tfs = null;
        
        public static Program Current = null;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Program());
        }

        public Program()
        {
            InitializeContext();
            InitializeService();
            Program.Current = this;
        }

        private void InitializeContext()
        {
            this.components = new System.ComponentModel.Container();
            this.tfsBuildAlertNotifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
            this.tfsBuildAlertNotifyIconContextMenu = new System.Windows.Forms.ContextMenu();
            this.settingsContextMenuItem = new System.Windows.Forms.MenuItem();
            this.resetContextMenuItem = new System.Windows.Forms.MenuItem();
            this.exitContextMenuItem = new System.Windows.Forms.MenuItem();

            this._okIcon = new Icon(typeof(Program), "ok.ico");
            this._brokenIcon = new Icon(typeof(Program), "broken.ico");

            // 
            // NotifyIcon
            // 
            this.tfsBuildAlertNotifyIcon.ContextMenu = tfsBuildAlertNotifyIconContextMenu;
            this.tfsBuildAlertNotifyIcon.DoubleClick += new EventHandler(tfsBuildAlertNotifyIcon_DoubleClick);
            this.tfsBuildAlertNotifyIcon.Icon = this._okIcon;
            this.tfsBuildAlertNotifyIcon.Text = "TFSBuildAlert";
            this.tfsBuildAlertNotifyIcon.Visible = true;

            // 
            // NotifyIconContextMenu
            // 
            this.tfsBuildAlertNotifyIconContextMenu.MenuItems.AddRange(new MenuItem[] { settingsContextMenuItem, resetContextMenuItem, exitContextMenuItem });

            // 
            // settingsContextMenuItem
            // 
            this.settingsContextMenuItem.Index = 0;
            this.settingsContextMenuItem.Text = "&Configure";
            this.settingsContextMenuItem.DefaultItem = true;
            this.settingsContextMenuItem.Click += new System.EventHandler(this.settingsContextMenuItem_Click);

            // 
            // resetContextMenuItem
            // 
            this.resetContextMenuItem.Index = 1;
            this.resetContextMenuItem.Text = "&Reset";
            this.resetContextMenuItem.Click += new System.EventHandler(this.resetContextMenuItem_Click);

            // 
            // exitContextMenuItem
            // 
            this.exitContextMenuItem.Index = 2;
            this.exitContextMenuItem.Text = "&Exit";
            this.exitContextMenuItem.Click += new System.EventHandler(this.exitContextMenuItem_Click);
        }

        private void InitializeService()
        {
            // Open notification service
            _notificationHost = new ServiceHost(typeof(NotificationService));
            _notificationHost.Open();

            // Connect to TFS and register subscription for build completed events
            _tfs = new TeamFoundationServer(Settings.TFSServer, new UICredentialsProvider());
            _tfs.EnsureAuthenticated();
            SubscriptionService s = new SubscriptionService(_tfs, "TFSBuildAlert");        
            s.AddSubscription(TFSEventType.BuildCompletionEvent, _notificationHost.Description.Endpoints[0].Address.Uri.AbsoluteUri);
        }

        private void tfsBuildAlertNotifyIcon_DoubleClick(object sender, System.EventArgs e)
        {
            ConfigureSettings();
        }

        private void settingsContextMenuItem_Click(object sender, EventArgs e)
        {
            ConfigureSettings();
        }

        private void ConfigureSettings()
        {
            if (this.settingsForm == null)
            {
                this.settingsForm = new SettingsForm();
                this.settingsForm.ShowDialog();
                this.settingsForm = null;
            }
            else
            {
                this.settingsForm.BringToFront();
            }
        }
        
        private void resetContextMenuItem_Click(object sender, EventArgs e)
        {
            this.Reset();
        }

        private void exitContextMenuItem_Click(object sender, EventArgs e)
        {
            this.ExitThread();
        }

        public void Alert()
        {
            Alert(Settings.AlertCommand);
        }

        public void Alert(string command)
        {
            ExecuteCommand(command);
            this.tfsBuildAlertNotifyIcon.Icon = this._brokenIcon;
        }

        public void Reset()
        {
            Reset(Settings.ResetCommand);
        }

        public void Reset(string command)
        {
            ExecuteCommand(command);
            this.tfsBuildAlertNotifyIcon.Icon = this._okIcon;
        }

        private void ExecuteCommand(string command)
        {
            int pos = command.IndexOf(".exe") + 4;
            string fileName = command.Substring(0, pos);
            string arguments = command.Substring(pos + 1);
            Process.Start(fileName, arguments);
        }

    }
}